﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace FileStorage.Common.Filters
{
    public class MustLoginMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<MustLoginMiddleware> _logger;

        public MustLoginMiddleware(RequestDelegate next, ILogger<MustLoginMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context)
        {
            var request = context.Request;
            var response = context.Response;
            var session = context.Session;

            var url = request.GetEncodedPathAndQuery();
            // _logger.LogInformation("url = " + url);

            var account = session.GetString("ACCOUNT");

#if !DEBUG
            if (account == null)
            {
                account = "admin";
                session.SetString("ACCOUNT", account);
            }
#endif

            if (
               url.StartsWith("/css") ||
               url.StartsWith("/js") ||
               url.StartsWith("/fonts") ||
               url.StartsWith("/pdfview") ||
               url.StartsWith("/quickview") ||
               url.StartsWith("/externalLinksController") ||
               url.StartsWith("/resourceController") ||
               url.StartsWith("/dav") ||
               url.StartsWith("/swagger")
               )
            {
                await _next(context);
                return;
            }

            switch (url)
            {
                case "/":
                    Redirect(response, "/home.html");
                    return;
                case "/home.html":
                    if (account == null)
                    {
                        Redirect(response, "/prv/login.html");
                        return;
                    }
                    else
                    {
                        await _next(context);
                        return;
                    }
                case "/prv/login.html":
                    if (account == null)
                    {
                        await _next(context);
                        return;
                    }
                    else
                    {
                        Redirect(response, "/home.html");
                        return;
                    }
                case "/prv/forbidden.html":
                case "/prv/error.html":
                    Redirect(response, "/home.html");
                    return;
                case "/homeController/getNewVerCode.do":
                case "/homeController/askForAllowSignUpOrNot.ajax":
                case "/prv/signup.html":
                    await _next(context);
                    return;
            }

            if (ServerConfig.MustLogin)
            {
                if (url.EndsWith(".html") || url.EndsWith(".do"))
                {
                    if (account == null)
                    {
                        Redirect(response, "/prv/login.html");
                        return;
                    }

                    await _next(context);
                    return;
                }
                else if (url.EndsWith(".ajax"))
                {
                    if (url == "/homeController/doLogin.ajax" || url == "/homeController/getPublicKey.ajax" || url == "/homeController/doSigUp.ajax")
                    {
                        await _next(context);
                        return;
                    }
                    else if (account != null)
                    {
                        await _next(context);
                        return;
                    }
                    else
                    {
                        await Rewrite(response, "mustLogin");
                        return;
                    }
                }
                else
                {
                    await _next(context);
                    return;
                }
            }
            else
            {
                await _next(context);
                return;
            }
        }


        private void Redirect(HttpResponse response, string location)
        {
            response.StatusCode = 301;
            response.Headers["Location"] = location;
        }

        private async Task Rewrite(HttpResponse response, string content)
        {
            response.StatusCode = 200;
            response.ContentType = "text/plain";
            await response.WriteAsync(content);
        }
    }
}
